/************************************************************************
*************************************************************************
*************************************************************************

sharetest.ado

Runs the share test. Data must be xtset before calling sharetest.


Created by Ajay Shenoy, U.C. Santa Cruz
23 Aug 2018
azshenoy@ucsc.edu

DISCLAIMER: 
I provide this code as-is with no guarantee that it will deliver the
estimates you want. It's your responsibility to make sure the code is
doing what you expect. In other words, it's not my fault you had to
retract your paper...

If you notice errors you can get in touch by email. You can email me
questions, though my ability to reply promptly (or at all) is itself
a question.


Syntax:
syntax varlist [if], [TESTvars(varlist fv ts) DEGree(integer 2) CLUster(varname numeric) stub(name) CONtrols(varlist fv ts) mmerr lagtest lagdeg(integer 2)]

Example:
sharetest logshare k l m, test( l2c.( k##c.m ) ) lagtest


-Varlist-

[Log Share] [Log Input 1] [Log Input 2] ...

ex: sharetest logshare k l m, test( l2c.( k##c.m ) ) lagtest


-Options-

DEGree:		Degree of the polynomial approximation used for the nonparametric
			control function. (Default: 2)
CLUster:	Variable on which to cluster inference (Default: panelvar)

stub:		Stub for temporary variables created--we delete them later. Default: so_

CONtrols:	If we want to control for additional variables

TESTvars: 	Variables to test for significance

mmerr:		Pass to indicate we want to instrument control function

lagtest:	In addition to what's in TESTvars, test lags of the k-degree control function [cannot be specified with mmerr]

lagdeg:		If lagtest is passed, this is required. It's the degree of the lagged polynomial used in our test (default: 1)
*************************************************************************
*************************************************************************
************************************************************************/



/************************************************************************
*************************************************************************
Main Program
*************************************************************************
************************************************************************/




cap program drop sharetest
program sharetest, rclass

	syntax varlist [if], [TESTvars(varlist fv ts) DEGree(integer 2) CLUster(varname numeric) stub(name) CONtrols(varlist fv ts) iv(varlist fv ts)  mmerr lagtest lagdeg(integer 1)]
	
	quietly {
		
		//Save previous state
		tempfile pre
		save `pre'
		
		//Restrict sample if necessary
		if !mi("`if'") {
			keep `if'
		}
		
		
		xtset
		local id `r(panelvar)'
		local t `r(timevar)'
		
		
		/*************
		Check for errors in parameters
		**************/
		
		if !mi("`lagtest'") & !mi("`mmerr'") {
			noisily: di `"Cannot specify both "lagtest" and "mmerr""'
			error 198
		}
		
		if mi("`lagtest'") & mi("`testvars'") {
			noisily: di `"Must specify either "lagtest" or "testvars" or both"'
			error 102
		}
		

		

		
		/*************
		If they passed nothing for the last two parameters, set to default
		**************/
		
		
		if mi("`cluster'") {
			local cluster `id'
		}
		
		if mi("`stub'") {
			local stub "st_"
		}
		

		
		
		/*************
		Construct variable list
		**************/
		gettoken tmp1 tmp2: varlist
		
		gen `stub'share = `tmp1'
		
		local count 0
		foreach var of varlist `tmp2' {
			local ++count
			
			gen `stub'x`count' = `var'
		}


		
		
		/*************
		Prepare control function
		**************/
		
		/*
			This will just be a list of interactions (in the form of factor variables)
			that will later be passed to Stata
		*/
		
		local contem ""
		//local lagged ""
		
		forvalues p=1/`degree' {
			//If this is the first iteration, we have no prior interactions
			if mi("`contem'") {
				local contem "c.("
			}
			//Otherwise, we specify an interaction
			else {
				local contem "`contem'##c.("
			}
			
			
			foreach var of varlist `stub'x1-`stub'x`count'  {
				//Throw each variable into the parentheses
				local contem "`contem' `var'"
			}
			
			//Close the parentheses
			local contem "`contem')"
		}
		
		

		/*************
		Do we need lags?
		**************/
		sort `id' `t'
		
		if !mi("`lagtest'") {
			forvalues p=1/`lagdeg' {
				//If this is the first iteration, we have no prior interactions
				if mi("`laglist'") {
					local laglist "cl.("
				}
				//Otherwise, we specify an interaction
				else {
					local laglist "`laglist'##cl.("
				}
				
				
				foreach var of varlist `stub'x1-`stub'x`count'  {
					//Throw each variable into the parentheses
					local laglist "`laglist' `var'"
				}
				
				//Close the parentheses
				local laglist "`laglist')"
			}
		}
		
		if !mi("`mmerr'") {
		
		
			local laglist l.(`contem')
			
			/*/** Lags **/
			sort `id' `t'
			foreach var of varlist `stub'x1-`stub'x`count'  {
				gen `var'_l = l.`var'
				local laglist `laglist' `var'_l
			}*/
		}
		

		/*************
		Check for lagtest
		**************/
		if !mi("`lagtest'") {
			local testvars `testvars' `laglist'
		}
		

		
		/*************
		Run test
		**************/	
		
		//Deal with measurement error?
		if !mi("`mmerr'") {
			di "ivregress 2sls `stub'share `controls' `testvars' (`contem'=`laglist'), cluster(`cluster') small"
			ivregress 2sls `stub'share `controls' `testvars' (`contem'=`laglist'), cluster(`cluster') small
			
		}
		else if !mi("`iv'") {
			ivreg2  `stub'share `controls'  (`testvars'=`iv'), cluster(`cluster') small
			local widstat = e(widstat)
		}
		else {
			reg `stub'share `controls' `contem' `testvars', cluster(`cluster')
		}
		
		//Need to keep the sample consistent by including only obs that make it into the final regression
		gen  `stub'testsamp = e(sample)
		
		
		
		testparm `testvars'

		local F 	 	= r(F)
		local pval		= r(p)
		local N 	 	= e(N)
		local N_clust 	= e(N_clust)
		

		
		/*************
		Partial R-squared and Information Criteria
		(We don't need to cluster these regressions, as we're not using the standard errors)
		**************/
		


		if !mi("`mmerr'") {
			//Note: partial r-squared may not mean anything with IV
			ivregress 2sls `stub'share `controls' (`contem'=`laglist') if `stub'testsamp == 1, small
		}
		else if !mi("`iv'") {
			//Note: partial r-squared may not mean anything with IV
			reg `stub'share `controls'  if `stub'testsamp == 1
		}
		else {
			reg `stub'share `controls' `contem'  if `stub'testsamp == 1
		}
		local sse_red = e(rss)
		local k		  = e(rank)
		local n 	  = e(N)
		local aic_unc = 2*`k' - 2*e(ll)
		local bic_unc = log(`n')*`k' - 2*e(ll)
		
		if !mi("`mmerr'") {
			ivregress 2sls `stub'share `controls' `testvars' (`contem'=`laglist') if `stub'testsamp == 1, small
		}
		else if !mi("`iv'") {
			//Note: partial r-squared may not mean anything with IV
			ivregress 2sls `stub'share `controls'  (`testvars'=`iv') if `stub'testsamp == 1, small
		}
		else {
			reg `stub'share `controls' `contem' `testvars' if `stub'testsamp == 1
		}
		local sse_ful = e(rss)
		local k		  = e(rank)
		local aic_con = 2*`k' - 2*e(ll)
		local bic_con = log(`n')*`k' - 2*e(ll)
		
		local r2	= (`sse_red'-`sse_ful')/`sse_red'
		
		foreach stat in F pval r2 N N_clust aic_unc aic_con bic_unc bic_con {
			return scalar `stat' = ``stat''
		}
		
		if !mi("`iv'") {
			return scalar widstat = `widstat'
		}
		
		use `pre', clear
	}
	
	
	di "Testing stat:" _col(35) "`F'"
	di "P-value:" _col(35) "`pval'"
	di "AIC, Unconstrained Choices:" _col(35) "`aic_unc'"
	di "AIC, Constrained Choices:" _col(35) "`aic_con'"
	di "BIC, Unconstrained Choices:" _col(35) "`bic_unc'"
	di "BIC, Constrained Choices:" _col(35) "`bic_con'"
	di "Partial R-Squared:" _col(35) "`r2'"
	if !mi("`iv'") {
		di "IV Weak ID Stat:" _col(35) "`widstat'"
	}
	di _n _n "Testing vars:"
	di "`testvars'"

	
	
	
end

